package com.lyun.rabbitMQ.consumer;

import com.lyun.bo.LoveValueBo;
import com.lyun.constants.RabbitMQConstants;
import com.lyun.constants.RedisKeyConstants;
import com.lyun.pojo.LoveValue;
import com.lyun.service.LoveValueService;
import com.lyun.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * LoveValue的消费者
 */
@Component
@Slf4j
public class LoveValueListener {

    // 过期时间为1天
    private static final Long EXPIRATION_DAYS = 1L;

    private static final int LOCK_EXPIRE_TIME = 30;

    @Resource
    private LoveValueService loveValueService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitMQConstants.LOVE_VALUE_INSERT_QUEUE_NAME),
            exchange = @Exchange(
                    name = RabbitMQConstants.LOVE_VALUE_EXCHANGE_NAME
            ),
            key = {RabbitMQConstants.LOVE_VALUE_INSERT_KEY}
    ))
    public void loveValueInsertListener(LoveValueBo bo) {
        Double score = redisUtil.zGetScore(bo.getFromId().toString(), bo.getToId().toString());
        if (Objects.nonNull(score)) {
            return;
        }

        String lockKey = RedisKeyConstants.LOVE_VALUE_LOCK_PREFIX + bo.getFromId();
        //尝试获取分布式锁
        Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(
                lockKey, RedisKeyConstants.LOCK_DEFAULT_VALUE, LOCK_EXPIRE_TIME, TimeUnit.SECONDS);

        if (Boolean.TRUE.equals(lockAcquired)) {
            try {
                score = redisUtil.zGetScore(bo.getFromId().toString(), bo.getToId().toString());
                if (Objects.nonNull(score)) {
                    return;
                }
                LoveValue loveValue = new LoveValue();
                BeanUtils.copyProperties(bo, loveValue);

                Random ran = new Random();
                int ranNum = ran.nextInt(100) + 1;
                loveValue.setFateValue(ranNum);
                loveValueService.insertValue(loveValue);

                String key = RedisKeyConstants.LOVE_VALUE_PREFIX + bo.getFromId();
                //缓存进redis
                redisUtil.zAdd(key, bo.getToId().toString(), ranNum, EXPIRATION_DAYS, TimeUnit.DAYS);
            } finally {
                redisUtil.del(lockKey);
            }
        }
    }
}
